/**
  ******************************************************************************
  * File Name          : ttybsp.c
  * Description        : This file provides code for the configuration
  *                      of the USART instances.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include "bsp.h"

void SystemTTY_Config(void)
{
  timer_parameter_struct timer_initpara;
  
	rcu_periph_clock_enable(RCU_GPIOC);
  rcu_periph_clock_enable(RCU_GPIOD);
  rcu_periph_clock_enable(RCU_UART4);
  rcu_periph_clock_enable(TTY_TIMER_CLOCK);
  
	rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);

	/* configure the USART0 Tx pin and USART0 Rx pin */
	gpio_af_set(GPIOC, GPIO_AF_8, GPIO_PIN_12);
	gpio_af_set(GPIOD, GPIO_AF_8, GPIO_PIN_2);
	
	/* configure USART0 Tx as alternate function push-pull */
	gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_12);
	gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);

	/* configure USART0 Rx as alternate function push-pull */
	gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
	
	/* USART configure */
	usart_deinit(UART4);
	usart_baudrate_set(UART4, 115200u);
	usart_word_length_set(UART4, USART_WL_8BIT);
	usart_parity_config(UART4, USART_PM_NONE);
	usart_stop_bit_set(UART4, USART_STB_1BIT);
	usart_receive_config(UART4, USART_RECEIVE_ENABLE);
	usart_transmit_config(UART4, USART_TRANSMIT_ENABLE);
	usart_halfduplex_disable(UART4);
	usart_synchronous_clock_disable(UART4);
//	usart_receiver_timeout_threshold_config(UART4, 10000);
//	usart_receiver_timeout_disable(UART4);  /* 200M主频下,115200波特率超时时间约为每个计数8.68us */
	
  
  timer_deinit(TTY_TIMER);
	timer_struct_para_init(&timer_initpara);
	timer_initpara.prescaler         = 40000U;
  timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
  timer_initpara.counterdirection  = TIMER_COUNTER_UP;
  timer_initpara.period            = 50;
  timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
  timer_initpara.repetitioncounter = 0U;
	timer_init(TTY_TIMER, &timer_initpara);
	timer_auto_reload_shadow_enable(TTY_TIMER);
  timer_single_pulse_mode_config(TTY_TIMER, TIMER_SP_MODE_SINGLE);
  
	timer_interrupt_flag_clear(TTY_TIMER, TIMER_INT_FLAG_UP);
	timer_flag_clear(TTY_TIMER, TIMER_FLAG_UP);
  
  
	nvic_irq_enable(UART4_IRQn, TTY_UART_IRQ_PRIORITY, 0);
  nvic_irq_enable(TTY_TIMER_IRQn, TTY_TIMER_IRQ_PRIORITY, 0);
  
  
	usart_interrupt_enable(UART4, USART_INT_RBNE);
	usart_interrupt_disable(UART4, USART_INT_RT);
  timer_interrupt_enable(TTY_TIMER, TIMER_INT_UP);
	
  
  timer_disable(TTY_TIMER);
  
	usart_enable(UART4);
}

void Systty_SendBuf(const uint8_t *buf, uint32_t len)
{
	uint32_t i;
  
	for(i=0; i<len; i++)
	{
    USART_DATA(UART4) = (buf[i]& (uint16_t)0x01FFu);
    while(!(USART_STAT0(UART4) & USART_STAT0_TBE));
	}
}

void Systty_SendStr(const char *buf)
{
	uint32_t i;
  
	for(i=0; buf[i]!='\0'; i++)
	{
    USART_DATA(UART4) = (buf[i]& (uint16_t)0x01FFU);
    while(!(USART_STAT0(UART4) & USART_STAT0_TBE));
	}
}

extern void Terminal_RecvIsr(uint8_t dat);
extern void Terminal_BreakIsr(void);
/**
  * @brief This function handles USART1 global interrupt.
  */
void UART4_IRQHandler(void)
{
	if(usart_interrupt_flag_get(UART4, USART_INT_FLAG_RBNE) != RESET)
	{
    TIMER_CTL0(TTY_TIMER) &= ~(uint32_t)TIMER_CTL0_CEN;
    
		Terminal_RecvIsr(USART_DATA(UART4));
    
    TIMER_CNT(TTY_TIMER) = (uint32_t)0;
		TIMER_CTL0(TTY_TIMER) |= (uint32_t)TIMER_CTL0_CEN;
	}
  
//	if(usart_interrupt_flag_get(UART4, USART_INT_FLAG_RT) != RESET)
//	{
//		usart_interrupt_flag_clear(UART4, USART_INT_FLAG_RT);
//	}
}

void TTY_TIMER_IRQHandler(void)
{
	if(timer_interrupt_flag_get(TTY_TIMER, TIMER_INT_FLAG_UP) != RESET)
	{
		timer_interrupt_flag_clear(TTY_TIMER, TIMER_INT_FLAG_UP);
    
    Terminal_BreakIsr();
	}
}

/* printf */
FILE __stdout;

int fputc(int ch, FILE *f)
{
  USART_DATA(UART4) = ( (uint8_t)ch & (uint16_t)0x01FF );
  while(!(USART_STAT0(UART4) & USART_STAT0_TBE));

  return (ch);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
